#pragma once

#include <string>

#include "noncopyable.h"

#define LOG_INFO(logmsg_format, ...)                        \
    do                                                      \
    {                                                       \
        Logger &log = Logger::get_instance();               \
        log.set_logger_level(Logger_level::INFO);           \
        char buff[1024] = {0};                              \
        snprintf(buff, 1024, logmsg_format, ##__VA_ARGS__); \
        log.log(buff);                                      \
    } while (0)

#define LOG_ERROR(logmsg_format, ...)                       \
    do                                                      \
    {                                                       \
        Logger &log = Logger::get_instance();               \
        log.set_logger_level(Logger_level::ERROR);          \
        char buff[1024] = {0};                              \
        snprintf(buff, 1024, logmsg_format, ##__VA_ARGS__); \
        log.log(buff);                                      \
    } while (0)

#define LOG_FATAL(logmsg_format, ...)                       \
    do                                                      \
    {                                                       \
        Logger &log = Logger::get_instance();               \
        log.set_logger_level(Logger_level::FATAL);          \
        char buff[1024] = {0};                              \
        snprintf(buff, 1024, logmsg_format, ##__VA_ARGS__); \
        log.log(buff);                                      \
        exit(-1);                                           \
    } while (0)

#ifdef MUDEBUG
#define LOG_DEBUG(logmsg_format, ...)                       \
    do                                                      \
    {                                                       \
        Logger &log = Logger::get_instance();               \
        log.set_logger_level(Logger_level::DEBUG);          \
        char buff[1024] = {0};                              \
        snprintf(buff, 1024, logmsg_format, ##__VA_ARGS__); \
        log.log(buff);                                      \
    } while (0) #else
#define LOG_DEBUG(logmsg_format, ...)
#endif

enum Logger_level
{
    INFO,
    ERROR,
    FATAL,
    DEBUG
};

class Logger : Noncopyable
{
private:
    Logger() {};
    Logger_level logger_lever_;

public:
    static Logger &get_instance();
    void log(const std::string &msg);
    void set_logger_level(Logger_level log_level);
};
